home *** CD-ROM | disk | FTP | other *** search
/ Gekikoh Dennoh Club 5 / Gekikoh Dennoh Club Vol. 5 (Japan).7z / Gekikoh Dennoh Club Vol. 5 (Japan) (Track 01).bin / internet / xip / iijppp.lzh / src / lcp.c < prev    next >
C/C++ Source or Header  |  1994-10-14  |  15KB  |  650 lines

  1. /*
  2.  *          PPP Link Control Protocol (LCP) Module
  3.  *
  4.  *        Written by Toshiharu OHNO (tony-o@iij.ad.jp)
  5.  *
  6.  *   Copyright (C) 1993, Internet Initiative Japan, Inc. All rights reserverd.
  7.  *
  8.  * Redistribution and use in source and binary forms are permitted
  9.  * provided that the above copyright notice and this paragraph are
  10.  * duplicated in all such forms and that any documentation,
  11.  * advertising materials, and other materials related to such
  12.  * distribution and use acknowledge that the software was developed
  13.  * by the Internet Initiative Japan, Inc.  The name of the
  14.  * IIJ may not be used to endorse or promote products derived
  15.  * from this software without specific prior written permission.
  16.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  17.  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  18.  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  19.  *
  20.  * TODO:
  21.  *      o Validate magic number received from peer.
  22.  *    o Limit data field length by MRU
  23.  */
  24. #include "fsm.h"
  25. #include "lcp.h"
  26. #include "ipcp.h"
  27. #include "lcpproto.h"
  28. #include "os.h"
  29. #include "hdlc.h"
  30. #include "lqr.h"
  31. #include "phase.h"
  32. #include "vars.h"
  33.  
  34. extern void IpcpUp();
  35. extern void IpcpOpen();
  36. extern void SendPapChallenge();
  37. extern void SendChapChallenge();
  38. extern void SetLinkParams(struct lcpstate *);
  39. extern void Prompt();
  40. extern void StopIdleTimer();
  41. extern void HdlcInit();
  42. extern void OsLinkdown();
  43. extern void Cleanup();
  44.  
  45. struct lcpstate LcpInfo;
  46.  
  47. static void LcpSendConfigReq(struct fsm *);
  48. static void LcpSendTerminateReq(struct fsm *fp);
  49. static void LcpSendTerminateAck(struct fsm *fp);
  50. static void LcpDecodeConfig(struct mbuf *bp, int mode);
  51. static void LcpInitRestartCounter(struct fsm *);
  52. static void LcpLayerUp(struct fsm *);
  53. static void LcpLayerDown(struct fsm *);
  54. static void LcpLayerStart(struct fsm *);
  55. static void LcpLayerFinish(struct fsm *);
  56.  
  57. extern int ModemSpeed();
  58.  
  59. #define    REJECTED(p, x)    (p->his_reject & (1<<x))
  60.  
  61. static char *cftypes[] = {
  62.   "???", "MRU", "ACCMAP", "AUTHPROTO", "QUALPROTO", "MAGICNUM",
  63.   "RESERVED", "PROTOCOMP", "ACFCOMP", "FCSALT", "SDP",
  64. };
  65.  
  66. struct fsm LcpFsm = {
  67.   "LCP",            /* Name of protocol */
  68.   PROTO_LCP,            /* Protocol Number */
  69.   LCP_MAXCODE,
  70.   OPEN_ACTIVE,
  71.   ST_INITIAL,            /* State of machine */
  72.   0, 0, 0,
  73.  
  74.   0,
  75.   { 0, 0, 0, NULL, NULL, NULL },
  76.  
  77.   LcpLayerUp,
  78.   LcpLayerDown,
  79.   LcpLayerStart,
  80.   LcpLayerFinish,
  81.   LcpInitRestartCounter,
  82.   LcpSendConfigReq,
  83.   LcpSendTerminateReq,
  84.   LcpSendTerminateAck,
  85.   LcpDecodeConfig,
  86. };
  87.  
  88. static struct pppTimer LcpReportTimer;
  89.  
  90. char *PhaseNames[] = {
  91.   "Dead", "Establish", "Authenticate", "Network", "Terminate"
  92. };
  93.  
  94. void
  95. NewPhase(new)
  96. int new;
  97. {
  98.   struct lcpstate *lcp = &LcpInfo;
  99.  
  100.   phase = new;
  101.   LogPrintf(LOG_PHASE, "Phase: %s\n", PhaseNames[phase]);
  102.   switch (phase) {
  103.   case PHASE_AUTHENTICATE:
  104.     lcp->auth_ineed = lcp->want_auth;
  105.     lcp->auth_iwait = lcp->his_auth;
  106.     LogPrintf(LOG_PHASE, " his = %x, mine = %x\n", lcp->his_auth, lcp->want_auth);
  107.     if (lcp->his_auth || lcp->want_auth) {
  108.       if (lcp->his_auth == PROTO_PAP)
  109.     SendPapChallenge();
  110.       if (lcp->want_auth == PROTO_CHAP)
  111.     SendChapChallenge();
  112.     } else
  113.       NewPhase(PHASE_NETWORK);
  114.     break;
  115.   case PHASE_NETWORK:
  116.     IpcpUp();
  117.     IpcpOpen();
  118.     CcpUp();
  119.     CcpOpen();
  120.     break;
  121.   case PHASE_DEAD:
  122.     if (mode & MODE_DIRECT)
  123.       Cleanup(EX_DEAD);
  124.     break;
  125.   }
  126. }
  127.  
  128. static void
  129. LcpReportTime()
  130. {
  131. #ifdef VERBOSE
  132.   time_t t;
  133.  
  134.   time(&t);
  135.   logprintf("%s", ctime(&t));
  136. #endif
  137.   StopTimer(&LcpReportTimer);
  138.   LcpReportTimer.state = TIMER_STOPPED;
  139.   StartTimer(&LcpReportTimer);
  140.   HdlcErrorCheck();
  141. }
  142.  
  143. int
  144. ReportLcpStatus()
  145. {
  146.   struct lcpstate *lcp = &LcpInfo;
  147.   struct fsm *fp = &LcpFsm;
  148.  
  149.   printf("%s [%s]\n", fp->name, StateNames[fp->state]);
  150.   printf(
  151.     " his side: MRU %d, ACCMAP %08x, PROTOCOMP %d, ACFCOMP %d MAGIC %08x\n",
  152.     lcp->his_mru, lcp->his_accmap, lcp->his_protocomp, lcp->his_acfcomp, lcp->his_magic);
  153.   printf(
  154.     " my  side: MRU %d, ACCMAP %08x, PROTOCOMP %d, ACFCOMP %d MAGIC %08x\n",
  155.     lcp->want_mru, lcp->want_accmap, lcp->want_protocomp, lcp->want_acfcomp, lcp->want_magic);
  156.   printf("\nDefaults:   MRU = %d, ACCMAP = %08x\t", VarMRU, VarAccmap);
  157.   printf("Open Mode: %s\n", (VarOpenMode == OPEN_ACTIVE)? "active" : "passive");
  158.   return(1);
  159. }
  160.  
  161. /*
  162.  * Generate random number which will be used as magic number.
  163.  */
  164. u_long
  165. GenerateMagic()
  166. {
  167.   time_t tl;
  168.   struct timeval tval;
  169.  
  170.   time(&tl);
  171.   gettimeofday(&tval, NULL);
  172.   tl += tval.tv_sec ^ tval.tv_usec + getppid();
  173.   tl *= getpid();
  174.   return(tl);
  175. }
  176.  
  177. void
  178. LcpInit()
  179. {
  180.   struct lcpstate *lcp = &LcpInfo;
  181.  
  182.   FsmInit(&LcpFsm);
  183.   HdlcInit();
  184.  
  185.   bzero(lcp, sizeof(struct lcpstate));
  186.   lcp->want_mru = VarMRU;
  187.   lcp->his_mru = DEF_MRU;
  188.   lcp->his_accmap = 0xffffffff;
  189.   lcp->want_accmap = VarAccmap;
  190.   lcp->want_magic = GenerateMagic();
  191.   lcp->want_auth = lcp->his_auth = 0;
  192.   if (Enabled(ConfChap))
  193.     lcp->want_auth = PROTO_CHAP;
  194.   else if (Enabled(ConfPap))
  195.     lcp->want_auth = PROTO_PAP;
  196.   if (Enabled(ConfLqr)) lcp->want_lqrperiod = VarLqrTimeout * 100;
  197.   if (Enabled(ConfAcfcomp)) lcp->want_acfcomp = 1;
  198.   if (Enabled(ConfProtocomp)) lcp->want_protocomp = 1;
  199.   LcpFsm.maxconfig = 10;
  200. }
  201.  
  202. static void
  203. LcpInitRestartCounter(fp)
  204. struct fsm *fp;
  205. {
  206.   fp->FsmTimer.load = 5 * SECTICKS;
  207.   fp->restart = 5;
  208. }
  209.  
  210. void
  211. PutConfValue(cpp, types, type, len, val)
  212. u_char **cpp;
  213. char **types;
  214. u_char type;
  215. int len;
  216. u_long val;
  217. {
  218.   u_char *cp;
  219.  
  220.   cp = *cpp;
  221.   *cp++ = type; *cp++ = len;
  222.   if (len == 6) {
  223.     if (type == TY_IPADDR) {
  224.       LogPrintf(LOG_LCP, " %s [%d] %s\n",
  225.     types[type], len, inet_ntoa(htonl(val)));
  226.     } else {
  227.       LogPrintf(LOG_LCP, " %s [%d] %08x\n", types[type], len, val);
  228.     }
  229.     *cp++ = (val >> 24) & 0377;
  230.     *cp++ = (val >> 16) & 0377;
  231.   } else
  232.     LogPrintf(LOG_LCP, " %s [%d] %d\n", types[type], len, val);
  233.   *cp++ = (val >> 8) & 0377;
  234.   *cp++ = val & 0377;
  235.   *cpp = cp;
  236. }
  237.  
  238. static void
  239. LcpSendConfigReq(fp)
  240. struct fsm *fp;
  241. {
  242.   u_char *cp;
  243.   struct lcpstate *lcp = &LcpInfo;
  244.   struct lqrreq *req;
  245.  
  246.   LogPrintf(LOG_LCP, "%s: SendConfigReq\n", fp->name);
  247.   cp = ReqBuff;
  248.   if (lcp->want_acfcomp && !REJECTED(lcp, TY_ACFCOMP)) {
  249.     *cp++ = TY_ACFCOMP; *cp++ = 2;
  250.     LogPrintf(LOG_LCP, " %s\n", cftypes[TY_ACFCOMP]);
  251.   }
  252.   if (lcp->want_protocomp && !REJECTED(lcp, TY_PROTOCOMP)) {
  253.     *cp++ = TY_PROTOCOMP; *cp++ = 2;
  254.     LogPrintf(LOG_LCP, " %s\n", cftypes[TY_PROTOCOMP]);
  255.   }
  256.   if (!REJECTED(lcp, TY_MRU))
  257.     PutConfValue(&cp, cftypes, TY_MRU, 4, lcp->want_mru);
  258.   if (!REJECTED(lcp, TY_ACCMAP))
  259.     PutConfValue(&cp, cftypes, TY_ACCMAP, 6, lcp->want_accmap);
  260.   if (lcp->want_magic && !REJECTED(lcp, TY_MAGICNUM))
  261.     PutConfValue(&cp, cftypes, TY_MAGICNUM, 6, lcp->want_magic);
  262.   if (lcp->want_lqrperiod && !REJECTED(lcp, TY_QUALPROTO)) {
  263.     req = (struct lqrreq *)cp;
  264.     req->type = TY_QUALPROTO; req->length = sizeof(struct lqrreq);
  265.     req->proto = htons(PROTO_LQR);
  266.     req->period = htonl(lcp->want_lqrperiod);
  267.     cp += sizeof(struct lqrreq);
  268.     LogPrintf(LOG_LCP, " %s (%d)\n", cftypes[TY_QUALPROTO], lcp->want_lqrperiod);
  269.   }
  270.   switch (lcp->want_auth) {
  271.   case PROTO_PAP:
  272.     PutConfValue(&cp, cftypes, TY_AUTHPROTO, 4, lcp->want_auth);
  273.     break;
  274.   case PROTO_CHAP:
  275.     PutConfValue(&cp, cftypes, TY_AUTHPROTO, 5, lcp->want_auth);
  276.     *cp++ = 5;        /* Use MD5 */
  277.     break;
  278.   }
  279.   FsmOutput(fp, CODE_CONFIGREQ, fp->reqid++, ReqBuff, cp - ReqBuff);
  280. }
  281.  
  282. void
  283. LcpSendProtoRej(option, count)
  284. u_char *option;
  285. int count;
  286. {
  287.   struct fsm *fp = &LcpFsm;
  288.  
  289.   LogPrintf(LOG_LCP, "%s: SendProtoRej\n", fp->name);
  290.   FsmOutput(fp, CODE_PROTOREJ, fp->reqid, option, count);
  291. }
  292.  
  293. static void
  294. LcpSendTerminateReq(fp)
  295. struct fsm *fp;
  296. {
  297.    /* Most thins are done in fsm layer. Nothing to to. */
  298. }
  299.  
  300. static void
  301. LcpSendTerminateAck(fp)
  302. struct fsm *fp;
  303. {
  304.   LogPrintf(LOG_LCP, "%s: SendTerminateAck.\n", fp->name);
  305.   FsmOutput(fp, CODE_TERMACK, fp->reqid++, NULL, 0);
  306. }
  307.  
  308. static void
  309. LcpLayerStart(fp)
  310. struct fsm *fp;
  311. {
  312.   LogPrintf(LOG_LCP, "%s: LayerStart\n", fp->name);
  313.   NewPhase(PHASE_ESTABLISH);
  314. }
  315.  
  316. static void
  317. LcpLayerFinish(fp)
  318. struct fsm *fp;
  319. {
  320. #ifdef VERBOSE
  321.   fprintf(stderr, "%s: LayerFinish\r\n", fp->name);
  322. #endif
  323.   Prompt(1);
  324.   LogPrintf(LOG_LCP, "%s: LayerFinish\n", fp->name);
  325. #ifdef notdef
  326.   OsCloseLink(0);
  327. #else
  328.   OsCloseLink(1);
  329. #endif
  330.   NewPhase(PHASE_DEAD);
  331.   StopTimer(&LcpReportTimer);
  332.   StopIdleTimer();
  333.   OsInterfaceDown(0);
  334. }
  335.  
  336. static void
  337. LcpLayerUp(fp)
  338. struct fsm *fp;
  339. {
  340.   LogPrintf(LOG_LCP, "%s: LayerUp\n", fp->name);
  341.   OsSetInterfaceParams(23, LcpInfo.his_mru, ModemSpeed());
  342.   SetLinkParams(&LcpInfo);
  343.  
  344.   NewPhase(PHASE_AUTHENTICATE);
  345.  
  346.   StartLqm();
  347.   StopTimer(&LcpReportTimer);
  348.   LcpReportTimer.state = TIMER_STOPPED;
  349.   LcpReportTimer.load = 60 * SECTICKS;
  350.   LcpReportTimer.func = LcpReportTime;
  351.   StartTimer(&LcpReportTimer);
  352. }
  353.  
  354. static void
  355. LcpLayerDown(fp)
  356. struct fsm *fp;
  357. {
  358.   LogPrintf(LOG_LCP, "%s: LayerDown\n", fp->name);
  359.   OsLinkdown();
  360.   NewPhase(PHASE_TERMINATE);
  361. }
  362.  
  363. void
  364. LcpUp()
  365. {
  366.   FsmUp(&LcpFsm);
  367. }
  368.  
  369. void
  370. LcpDown()
  371. {
  372.   NewPhase(PHASE_DEAD);
  373.   FsmDown(&LcpFsm);
  374. }
  375.  
  376. void
  377. LcpOpen(mode)
  378. int mode;
  379. {
  380.   LcpFsm.open_mode = mode;
  381.   FsmOpen(&LcpFsm);
  382. }
  383.  
  384. void
  385. LcpClose()
  386. {
  387.   FsmClose(&LcpFsm);
  388. }
  389.  
  390. /*
  391.  *    XXX: Should validate option length
  392.  */
  393. static void
  394. LcpDecodeConfig(bp, mode)
  395. struct mbuf *bp;
  396. int mode;
  397. {
  398.   u_char *cp;
  399.   char *request;
  400.   int plen, type, length, mru;
  401.   u_long *lp, magic, accmap;
  402.   u_short *sp, proto;
  403.   struct lqrreq *req;
  404.  
  405.   plen = plength(bp);
  406.  
  407.   cp = MBUF_CTOP(bp);
  408.   ackp = AckBuff;
  409.   nakp = NakBuff;
  410.   rejp = RejBuff;
  411.  
  412.   while (plen >= sizeof(struct fsmconfig)) {
  413.     type = *cp;
  414.     length = cp[1];
  415.     if (type <= TY_ACFCOMP)
  416.       request = cftypes[type];
  417.     else
  418.       request = "???";
  419.  
  420.     switch (type) {
  421.     case TY_MRU:
  422.       sp = (u_short *)(cp + 2);
  423.       mru = htons(*sp);
  424.       LogPrintf(LOG_LCP, " %s %d\n", request, mru);
  425.  
  426.       switch (mode) {
  427.       case MODE_REQ:
  428.     if (mru > MAX_MRU) {
  429.       *sp = htons(MAX_MRU);
  430.       bcopy(cp, nakp, 4); nakp += 4;
  431.     } else if (mru < MIN_MRU) {
  432.       *sp = htons(MIN_MRU);
  433.       bcopy(cp, nakp, 4); nakp += 4;
  434.     } else {
  435.       LcpInfo.his_mru = mru;
  436.       bcopy(cp, ackp, 4); ackp += 4;
  437.     }
  438.     break;
  439.       case MODE_NAK:
  440.     if (mru >= MIN_MRU || mru <= MAX_MRU)
  441.       LcpInfo.want_mru = mru;
  442.     break;
  443.       case MODE_REJ:
  444.     LcpInfo.his_reject |= (1 << type);
  445.     break;
  446.       }
  447.       break;
  448.     case TY_ACCMAP:
  449.       lp = (u_long *)(cp + 2);
  450.       accmap = htonl(*lp);
  451.       LogPrintf(LOG_LCP, " %s %08x\n", request, accmap);
  452.  
  453.       switch (mode) {
  454.       case MODE_REQ:
  455.     LcpInfo.his_accmap = accmap;
  456.     bcopy(cp, ackp, 6); ackp += 6;
  457.     break;
  458.       case MODE_NAK:
  459.     LcpInfo.want_accmap = accmap;
  460.     break;
  461.       case MODE_REJ:
  462.     LcpInfo.his_reject |= (1 << type);
  463.     break;
  464.       }
  465.       break;
  466.     case TY_AUTHPROTO:
  467.       sp = (u_short *)(cp + 2);
  468.       proto = ntohs(*sp);
  469.       LogPrintf(LOG_LCP, " %s proto = %x\n", request, proto);
  470.  
  471.       switch (mode) {
  472.       case MODE_REQ:
  473.     switch (proto) {
  474.     case PROTO_PAP:
  475.       if (length != 4) {
  476.         LogPrintf(LOG_LCP, " %s bad length (%d)\n", request, length);
  477.         goto reqreject;
  478.       }
  479.       if (Acceptable(ConfPap)) {
  480.         LcpInfo.his_auth = proto;
  481.         bcopy(cp, ackp, length); ackp += length;
  482.       } else if (Acceptable(ConfChap)) {
  483.         *nakp++ = *cp; *nakp++ = 5;
  484.         *nakp++ = PROTO_CHAP >> 8; *nakp++ = PROTO_CHAP;
  485.         *nakp++ = 5;
  486.       } else
  487.         goto reqreject;
  488.       break;
  489.     case PROTO_CHAP:
  490.       if (length < 5) {
  491.         LogPrintf(LOG_LCP, " %s bad length (%d)\n", request, length);
  492.         goto reqreject;
  493.       }
  494.       if (Acceptable(ConfChap) && cp[4] == 5) {
  495.         LcpInfo.his_auth = proto;
  496.         bcopy(cp, ackp, length); ackp += length;
  497.       } else if (Acceptable(ConfPap)) {
  498.         *nakp++ = *cp; *nakp++ = 4;
  499.         *nakp++ = PROTO_PAP >> 8; *nakp++ = PROTO_PAP;
  500.       } else
  501.         goto reqreject;
  502.       break;
  503.     default:
  504.       LogPrintf(LOG_LCP, " %s not implemented.\n", request);
  505.       goto reqreject;
  506.     }
  507.     break;
  508.       case MODE_NAK:
  509.     break;
  510.       case MODE_REJ:
  511.     LcpInfo.his_reject |= (1 << type);
  512.     break;
  513.       }
  514.       break;
  515.     case TY_QUALPROTO:
  516.       req = (struct lqrreq *)cp;
  517.       LogPrintf(LOG_LCP, " %s proto: %x, interval: %dms\n",
  518.         request, ntohs(req->proto), ntohl(req->period)*10);
  519.       switch (mode) {
  520.       case MODE_REQ:
  521.     if (ntohs(req->proto) != PROTO_LQR || !Acceptable(ConfLqr))
  522.       goto reqreject;
  523.     else {
  524.       LcpInfo.his_lqrperiod = ntohl(req->period);
  525.       if (LcpInfo.his_lqrperiod < 500)
  526.         LcpInfo.his_lqrperiod = 500;
  527.       req->period = htonl(LcpInfo.his_lqrperiod);
  528.       bcopy(cp, ackp, length); ackp += length;
  529.     }
  530.     break;
  531.       case MODE_NAK:
  532.     break;
  533.       case MODE_REJ:
  534.     LcpInfo.his_reject |= (1 << type);
  535.     break;
  536.       }
  537.       break;
  538.     case TY_MAGICNUM:
  539.       lp = (u_long *)(cp + 2);
  540.       magic = ntohl(*lp);
  541.       LogPrintf(LOG_LCP, " %s %08x\n", request, magic);
  542.  
  543.       switch (mode) {
  544.       case MODE_REQ:
  545.     if (LcpInfo.want_magic) {
  546.       /* XXX: Shoud validate magic number */
  547.       if (magic == LcpInfo.want_magic)
  548.         logprintf("magic is same!! %x, %x, %x\n",
  549.         magic, LcpInfo.want_magic, LcpInfo.his_magic);
  550.       LcpInfo.his_magic = magic;
  551.       bcopy(cp, ackp, length); ackp += length;
  552.     } else {
  553.       LcpInfo.my_reject |= (1 << type);
  554.       goto reqreject;
  555.     }
  556.     break;
  557.       case MODE_NAK:
  558.     LogPrintf(LOG_LCP, " %s magic %08x has NAKed\n", request, magic);
  559.     LcpInfo.want_magic = GenerateMagic();
  560.     break;
  561.       case MODE_REJ:
  562.     LogPrintf(LOG_LCP, " %s magic has REJected\n", request);
  563.     LcpInfo.want_magic = 0;
  564.     LcpInfo.his_reject |= (1 << type);
  565.     break;
  566.       }
  567.       break;
  568.     case TY_PROTOCOMP:
  569.       LogPrintf(LOG_LCP, " %s\n", request);
  570.  
  571.       switch (mode) {
  572.       case MODE_REQ:
  573.         if (Acceptable(ConfProtocomp)) {
  574.       LcpInfo.his_protocomp = 1;
  575.       bcopy(cp, ackp, 2); ackp += 2;
  576.         } else {
  577. #ifdef OLDMST
  578.       /*
  579.        * MorningStar before v1.3 needs NAK
  580.        */
  581.       bcopy(cp, nakp, 2); nakp += 2;
  582. #else
  583.       bcopy(cp, rejp, 2); rejp += 2;
  584.       LcpInfo.my_reject |= (1 << type);
  585. #endif
  586.         }
  587.     break;
  588.       case MODE_NAK:
  589.       case MODE_REJ:
  590.     LcpInfo.want_protocomp = 0;
  591.     LcpInfo.his_reject |= (1 << type);
  592.     break;
  593.       }
  594.       break;
  595.     case TY_ACFCOMP:
  596.       LogPrintf(LOG_LCP, " %s\n", request);
  597.       switch (mode) {
  598.       case MODE_REQ:
  599.         if (Acceptable(ConfAcfcomp)) {
  600.       LcpInfo.his_acfcomp = 1;
  601.       bcopy(cp, ackp, 2);
  602.       ackp += 2;
  603.         } else {
  604. #ifdef OLDMST
  605.       /*
  606.        * MorningStar before v1.3 needs NAK
  607.        */
  608.       bcopy(cp, nakp, 2);
  609.       nakp += 2;
  610. #else
  611.       bcopy(cp, rejp, 2);
  612.       rejp += 2;
  613.       LcpInfo.my_reject |= (1 << type);
  614. #endif
  615.     }
  616.     break;
  617.       case MODE_NAK:
  618.       case MODE_REJ:
  619.     LcpInfo.want_acfcomp = 0;
  620.     LcpInfo.his_reject |= (1 << type);
  621.     break;
  622.       }
  623.       break;
  624.     case TY_SDP:
  625.       LogPrintf(LOG_LCP, " %s\n", request);
  626.       switch (mode) {
  627.       case MODE_REQ:
  628.       case MODE_NAK:
  629.       case MODE_REJ:
  630.     break;
  631.       }
  632.       break;
  633.     default:
  634. reqreject:
  635.       bcopy(cp, rejp, length);
  636.       rejp += length;
  637.       LcpInfo.my_reject |= (1 << type);
  638.       break;
  639.     }
  640.     plen -= length;
  641.     cp += length;
  642.   }
  643. }
  644.  
  645. void
  646. LcpInput(struct mbuf *bp)
  647. {
  648.   FsmInput(&LcpFsm, bp);
  649. }
  650.